home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PCMania 44
/
PCMania CD44_1.iso
/
pcmania
/
mod44
/
mix.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-05
|
6KB
|
264 lines
// *** ------------------------------------- ***
// * Smp-Player , programado por *
// * Esteban Moreno Valdés *
// * ( Colaborador de la revista Pcmanía ) *
// *** ------------------------------------- ***
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
#include <dos.h>
#include <process.h>
#include <fcntl.h>
#include <io.h>
#define BYTE unsigned char
#define WORD unsigned int
BYTE far *data;
BYTE far *data2;
WORD constant=1,len,len2,freq,number,counter=0;
WORD RESET_PORT= 0x216;
WORD WRITE_PORT= 0x21C;
WORD READD_PORT= 0x21A;
WORD READS_PORT= 0x21E;
void sb_detect(void); // ¡¿¡ Está claro !?!
void load_info(char fichero[],char fichero2[]); // Carga el sample en memoria
void set_video_mode(BYTE); // Establece modo de pantalla especificado
void fin(void); // Muestra los creditos
void interrupt newint8(void); // Nuevo vector de interrupción
void interrupt (*oldint8)(void); // Antiguo vector de interrupción
void set_timer(void); // Establece nueva frecuencia
void res_timer(void); // Restaura antigua frecuencia
void write_dsp(BYTE);
void wait_dsp(void);
void main(int argc,char *argv[])
{
if (argc<3) {
clrscr();
fin();
printf("Error : Falta parámetro requerido.");
printf("\nSintaxis : MIX.EXE VOL1 FILE1.EXT VOL2 FILE2.EXT\n");
exit(0);
};
set_video_mode(0x03);
sb_detect();
load_info(argv[1],argv[2]);
freq=14000;
number = (WORD)(1193180l/freq);
set_timer();
write_dsp(0xD1);
oldint8=getvect(8);
setvect(8,newint8);
for(;constant<=len;) { }
write_dsp(0xD3);
res_timer();
setvect(8,oldint8); // Restauramos el vector de interrupción
farfree(data); // Liberamos la memoria utilizada
farfree(data2);
}
void load_info(char fichero[],char fichero2[])
{
int handle,handle2;
WORD n;
unsigned bytes_read,bytes_read2;
// Carga el primer y segundo sample en memoria
if ((_dos_open(fichero,O_RDONLY,&handle))!=0) {
printf(" Error : Fichero no encontrado : %s\n",fichero);
exit(0);
}
if ((_dos_open(fichero2,O_RDONLY,&handle2))!=0) {
printf(" Error : Fichero no encontrado : %s\n",fichero2);
exit(0);
}
len = (WORD)filelength(handle);
len2 = (WORD)filelength(handle2);
if (len<len2) { len=len2; }
if ( (data=(BYTE far*)farmalloc(len))==NULL) {
printf(" Error : No se puede asignar memoria correctamente.\n");
exit(0);
}
if ( (data2=(BYTE far*)farmalloc(len))==NULL) {
printf(" Error : No se puede asignar memoria correctamente.\n");
exit(0);
}
for (n=0;n<=len;n++) { *(data+n)=0; *(data2+n)=0; }
_dos_read(handle,(BYTE far*)data,len,&bytes_read);
_dos_close(handle);
_dos_read(handle2,(BYTE far*)data2,len2,&bytes_read2);
_dos_close(handle2);
printf("Mixing : %12s = %u\n",fichero,len);
printf(" %12s = %u\n\n",fichero2,len2);
}
void sb_detect(void)
{
BYTE valor=0;
WORD counter=1;
while (!valor) {
outportb(RESET_PORT,1);
delay(3); // Esperamos 3 milisegundos
outportb(RESET_PORT,0);
// Esperamos la disponibilidad
// de un byte en el puerto de
// datos
while (!(inportb(READS_PORT) & 128) || counter>=0xFFFF) counter++;
if (inportb(READD_PORT)!=0xAA) {
RESET_PORT+=0x10;
WRITE_PORT+=0x10;
READD_PORT+=0x10;
READS_PORT+=0x10;
if (RESET_PORT>=0x270) { valor=1;
fin();
printf(" No se ha detectado una tarjeta\n");
printf(" Sound-Blaster o compatible.\n\n");
}
}
else { valor=1;
fin();
printf(" ¡ Felicidades ! Se ha detectado una tarjeta\n");
printf(" SOUND_BLASTER o compatible, instalada en la\n");
printf(" Direcc. Puerto Base %Xh.\n\n",RESET_PORT-0x06);
}
}
}
void set_video_mode(BYTE mode)
{
asm {
xor ah,ah
mov al,mode
int 10h
}
}
void fin(void)
{
printf("╔════════════════════════════════════════╗\n");
printf("║ · Smp-Mix-Player · ║\n");
printf("║ Programado por Esteban Moreno Valdés ║\n");
printf("║ para la revista Pcmanía ║\n");
printf("╚════════════════════════════════════════╝\n\n");
}
void set_timer(void)
{
outportb(0x43,54);
outportb(0x40,(number & 0x00FF)); // Byte bajo
outportb(0x40,(number & 0xFF00)>>8); // Byte alto
}
void res_timer(void)
{
outportb(0x43,0x36); // Frecuencia del timer : 1193180
outportb(0x40,0); // Byte bajo
outportb(0x40,0); // Byte alto
}
void interrupt newint8(void)
{
WORD segment,offs,segment2,offs2;
segment=FP_SEG(data);
offs=FP_OFF(data);
segment2=FP_SEG(data2);
offs2=FP_OFF(data2);
asm {
call far ptr wait_dsp
mov al,10h
out dx,al // Modo directo
call far ptr wait_dsp
push ds
push es
mov ax,segment
mov ds,ax
mov si,offs
mov ax,segment2
mov es,ax
mov di,offs2
xor ax,ax
xor bx,bx
xor cx,cx
mov bl,[si] // Byte del primer instrumento
mov cl,es:[di] // Byte del segundo instrumento
pop es
pop ds
add bl,128 // Incluid esta líneas para las
add cl,128 // muestras con signo
add ax,bx
add ax,cx
shr ax,1
out dx,al
mov ax,number
add counter,ax
jnc B1
}
oldint8();
B1:;
asm {
mov dx,20h
mov al,20h
out dx,al // Fin de interrupción de hardware
}
constant++;
data++; // Incrementamos la dirección de
data2++; // los dos punteros
}
void write_dsp(BYTE dato)
{
asm push ax
asm mov dx,WRITE_PORT
bucle:;
asm in al,dx
asm test al,10000000b
asm jnz bucle
asm mov al,dato
asm out dx,al
asm pop ax
}
void wait_dsp(void)
{
asm push ax
asm mov dx,WRITE_PORT
bucle:;
asm in al,dx
asm test al,10000000b
asm jnz bucle
asm pop ax
}